// Arduino RFID读写器代码
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>

// RFID-RC522模块引脚定义
#define RST_PIN       9     // 标签读写器1
#define SS_PIN        10    // SDA
#define RST_PIN2      8     // 标签读写器2
#define SS_PIN2       7     // SDA

// 其他引脚定义
#define BUZZER_PIN    6
#define GREEN_LED_PIN 5
#define YELLOW_LED_PIN 4
#define RED_LED_PIN   3
#define BUTTON1_PIN   2
#define BUTTON2_PIN   11

// 初始化RFID模块
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522 mfrc522_2(SS_PIN2, RST_PIN2);

// 初始化LCD显示屏
LiquidCrystal_I2C lcd(0x27, 16, 2);

// 系统状态
bool inventoryMode = true; // true=入库模式, false=出库模式
unsigned long lastScanTime = 0;
const unsigned long SCAN_INTERVAL = 1000;

void setup() {
  Serial.begin(9600);
  SPI.begin();
  
  // 初始化RFID模块
  mfrc522.PCD_Init();
  mfrc522_2.PCD_Init();
  
  // 初始化LCD显示屏
  lcd.init();
  lcd.backlight();
  lcd.print("智能仓储系统");
  lcd.setCursor(0, 1);
  lcd.print("就绪");
  
  // 设置引脚模式
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(BUTTON1_PIN, INPUT_PULLUP);
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
  
  // 初始状态
  digitalWrite(GREEN_LED_PIN, HIGH);
  digitalWrite(YELLOW_LED_PIN, LOW);
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(BUZZER_PIN, LOW);
  
  // 蜂鸣器提示系统启动
  beep(200);
}

// 蜂鸣器发声函数
void beep(int duration) {
  digitalWrite(BUZZER_PIN, HIGH);
  delay(duration);
  digitalWrite(BUZZER_PIN, LOW);
}

// 读取RFID标签ID
String readRFIDTag(MFRC522 &rfid) {
  // 寻找新卡
  if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
    return "";
  }
  
  // 获取标签ID
  String tagID = "";
  for (byte i = 0; i < rfid.uid.size; i++) {
    if (rfid.uid.uidByte[i] < 0x10) tagID += "0";
    tagID += String(rfid.uid.uidByte[i], HEX);
  }
  tagID.toUpperCase();
  
  // 停止读卡
  rfid.PICC_HaltA();
  rfid.PCD_StopCrypto1();
  
  return tagID;
}

// 切换模式
void toggleMode() {
  inventoryMode = !inventoryMode;
  
  // 更新LCD显示
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("智能仓储系统");
  lcd.setCursor(0, 1);
  lcd.print(inventoryMode ? "入库模式" : "出库模式");
  
  // 模式切换提示
  beep(100);
  delay(100);
  beep(100);
  
  // 发送模式切换通知到Flask
  Serial.print("MODE:");
  Serial.println(inventoryMode ? "IN" : "OUT");
}

// 处理标签读取
void processTagRead(String tagID, int readerID) {
  // 更新LCD显示
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("标签: " + tagID.substring(0, 8));
  lcd.setCursor(0, 1);
  lcd.print(inventoryMode ? "入库" : "出库");
  
  // 点亮对应的LED
  digitalWrite(GREEN_LED_PIN, inventoryMode ? HIGH : LOW);
  digitalWrite(RED_LED_PIN, inventoryMode ? LOW : HIGH);
  
  // 蜂鸣器提示
  beep(200);
  
  // 发送标签信息到Flask
  String message = "TAG," + tagID + "," + (inventoryMode ? "IN" : "OUT") + "," + String(readerID);
  Serial.println(message);
  
  // 短暂延迟防止重复读取
  delay(500);
  
  // 恢复LED状态
  digitalWrite(GREEN_LED_PIN, HIGH);
  digitalWrite(RED_LED_PIN, LOW);
  
  // 恢复LCD显示
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("智能仓储系统");
  lcd.setCursor(0, 1);
  lcd.print(inventoryMode ? "入库模式" : "出库模式");
}

void loop() {
  unsigned long currentTime = millis();
  
  // 检查按钮状态
  if (digitalRead(BUTTON1_PIN) == LOW) {
    delay(50); // 消抖
    if (digitalRead(BUTTON1_PIN) == LOW) {
      toggleMode();
      while (digitalRead(BUTTON1_PIN) == LOW) {
        delay(10);
      }
    }
  }
  
  // 定期扫描RFID标签
  if (currentTime - lastScanTime >= SCAN_INTERVAL) {
    lastScanTime = currentTime;
    
    // 扫描第一个读写器
    String tag1 = readRFIDTag(mfrc522);
    if (tag1.length() > 0) {
      processTagRead(tag1, 1);
    }
    
    // 扫描第二个读写器
    String tag2 = readRFIDTag(mfrc522_2);
    if (tag2.length() > 0) {
      processTagRead(tag2, 2);
    }
  }
  
  // 检查来自Flask的命令
  if (Serial.available() > 0) {
    String command = Serial.readStringUntil('\n');
    command.trim();
    
    if (command == "BEEP") {
      beep(500);
    } else if (command == "STATUS") {
      // 返回系统状态
      String status = "STATUS," + (inventoryMode ? "IN" : "OUT");
      Serial.println(status);
    } else if (command.startsWith("DISPLAY:")) {
      // 在LCD上显示消息
      String message = command.substring(8);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(message.substring(0, 16));
      if (message.length() > 16) {
        lcd.setCursor(0, 1);
        lcd.print(message.substring(16, 32));
      }
    }
  }
  
  delay(100);
}